             package com.java.diagnostics.visualizer.gc.realtimeV2.parser;
             
             import com.java.diagnostics.visualizer.data.TupleDataBuilder;
             import com.java.diagnostics.visualizer.data.axes.AxisPair;
             import com.java.diagnostics.visualizer.data.axes.XDataAxis;
             import com.java.diagnostics.visualizer.factory.DataFactory;
             import com.java.diagnostics.visualizer.gc.realtime.util.Messages;
             import com.java.diagnostics.visualizer.metadata.TupleMetaData;
             import com.java.diagnostics.visualizer.metadata.TupleMetaData.TableField;
             import com.java.diagnostics.visualizer.metadata.TupleMetaData.TableType;
             import com.java.diagnostics.visualizer.parser.vgc.converters.GCNumberConverter;
             import org.xml.sax.Attributes;
             
             public class CommonData
             {
               static final String DETAILS = "details";
               static final String CLASS_UNLOADING = "classunloading";
               static final String REFS_CLEARED = "refs_cleared";
               static final String FINALIZATION = "finalization";
               static final String WARNING = "warning";
               static final String HEAP = "heap";
               static final String IMMORTAL = "immortal";
               private static final String OBJECTS_QUEUED = "objectsqueued";
               private static final String SOFT = "soft";
               private static final String WEAK = "weak";
               private static final String PHANTOM = "phantom";
               private static final String CLASSES = "classes";
               private static final String CLASSLOADERS = "classloaders";
               TupleDataBuilder meanFreeHeap;
               TupleDataBuilder minFreeHeap;
               TupleDataBuilder maxFreeHeap;
               TupleDataBuilder freeHeap;
               TupleDataBuilder meanFreeImmortal;
               TupleDataBuilder minFreeImmortal;
               TupleDataBuilder maxFreeImmortal;
               TupleDataBuilder minpriority;
               TupleDataBuilder maxpriority;
               TupleDataBuilder objectsQueuedForFinalization;
               TupleDataBuilder softRefsCleared;
               TupleDataBuilder weakRefsCleared;
               TupleDataBuilder phantomRefsCleared;
               TupleDataBuilder classesUnloaded;
               TupleDataBuilder classloadersUnloaded;
               TupleDataBuilder cycleIntervals;
               private long initialTimeMicros;
               private boolean hasInitialTime;
               private final GCEventHandler handler;
               final XDataAxis xAxis;
               double lastGCCycleMillis;
               private final GCNumberConverter gcNumberConverter;
               long currentGCNumber;
               
               CommonData(XDataAxis xAxis, GCEventHandler handler, GCNumberConverter gcNumberConverter, DataFactory factory, AxisPair heapAxisPair, AxisPair discreteNumberPair, AxisPair discreteTimePair)
               {
                 this.gcNumberConverter = gcNumberConverter;
                 this.handler = handler;
                 this.xAxis = xAxis;
                 this.freeHeap = factory
                 
                   .createTupleData("RealtimeLabels.free.heap.cycles", Messages.getString("RealtimeLabels.free.heap.cycles"), heapAxisPair);
                 this.minFreeHeap = factory
                 
                   .createTupleData("RealtimeLabels.free.heap.min", Messages.getString("RealtimeLabels.free.heap.min"), heapAxisPair);
                 this.maxFreeHeap = factory
                 
                   .createTupleData("RealtimeLabels.free.heap.max", Messages.getString("RealtimeLabels.free.heap.max"), heapAxisPair);
                 this.meanFreeHeap = factory
                 
                   .createTupleData("RealtimeLabels.free.heap.mean", Messages.getString("RealtimeLabels.free.heap.mean"), heapAxisPair);
                 this.minFreeImmortal = factory
                 
                   .createTupleData("RealtimeLabels.free.immortal.min", Messages.getString("RealtimeLabels.free.immortal.min"), heapAxisPair);
                 this.maxFreeImmortal = factory
                 
                   .createTupleData("RealtimeLabels.free.immortal.max", Messages.getString("RealtimeLabels.free.immortal.max"), heapAxisPair);
                 this.meanFreeImmortal = factory
                 
                   .createTupleData("RealtimeLabels.free.immortal.mean", Messages.getString("RealtimeLabels.free.immortal.mean"), heapAxisPair);
                 this.objectsQueuedForFinalization = factory
                 
                   .createTupleData("RealtimeLabels.objects.queued.for.finalization", Messages.getString("RealtimeLabels.objects.queued.for.finalization"), discreteNumberPair);
                 this.softRefsCleared = factory
                 
                   .createTupleData("RealtimeLabels.soft.references.cleared", Messages.getString("RealtimeLabels.soft.references.cleared"), discreteNumberPair);
                 this.weakRefsCleared = factory
                 
                   .createTupleData("RealtimeLabels.weak.references.cleared", Messages.getString("RealtimeLabels.weak.references.cleared"), discreteNumberPair);
                 this.phantomRefsCleared = factory
                 
                   .createTupleData("RealtimeLabels.phantom.references.cleared", Messages.getString("RealtimeLabels.phantom.references.cleared"), discreteNumberPair);
                 this.classesUnloaded = factory
                 
                   .createTupleData("RealtimeLabels.classes.unloaded", Messages.getString("RealtimeLabels.classes.unloaded"), discreteNumberPair);
                 this.classloadersUnloaded = factory
                 
                   .createTupleData("RealtimeLabels.class.loaders.unloaded", Messages.getString("RealtimeLabels.class.loaders.unloaded"), discreteNumberPair);
                 this.minpriority = factory
                 
                   .createTupleData("RealtimeLabels.min.gc.thread.priority", Messages.getString("RealtimeLabels.min.gc.thread.priority"), discreteNumberPair);
                 this.maxpriority = factory
                 
                   .createTupleData("RealtimeLabels.max.gc.thread.priority", Messages.getString("RealtimeLabels.max.gc.thread.priority"), discreteNumberPair);
                 this.cycleIntervals = factory
                 
                   .createTupleData("RealtimeLabels.cycle.intervals", Messages.getString("RealtimeLabels.cycle.intervals"), discreteTimePair);
                 
                 TupleMetaData meanFreeHeapMetaData = new TupleMetaData(TupleMetaData.TableType.ARITHMETIC, 
                   new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 this.meanFreeHeap.setTupleMetaData(meanFreeHeapMetaData);
                 TupleMetaData minFreeHeapMetaData = new TupleMetaData(TupleMetaData.TableType.ARITHMETIC, 
                   new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 this.minFreeHeap.setTupleMetaData(minFreeHeapMetaData);
                 TupleMetaData maxFreeHeapMetaData = new TupleMetaData(TupleMetaData.TableType.ARITHMETIC, 
                   new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 this.maxFreeHeap.setTupleMetaData(maxFreeHeapMetaData);
                 TupleMetaData freeHeapMetaData = new TupleMetaData(TupleMetaData.TableType.ARITHMETIC, 
                   new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 this.freeHeap.setTupleMetaData(freeHeapMetaData);
                 TupleMetaData meanFreeImmortalMetaData = new TupleMetaData(TupleMetaData.TableType.ARITHMETIC, 
                   new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 this.meanFreeImmortal.setTupleMetaData(meanFreeImmortalMetaData);
                 TupleMetaData minFreeImmortalMetaData = new TupleMetaData(TupleMetaData.TableType.ARITHMETIC, 
                   new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 this.minFreeImmortal.setTupleMetaData(minFreeImmortalMetaData);
                 TupleMetaData maxFreeImmortalMetaData = new TupleMetaData(TupleMetaData.TableType.ARITHMETIC, 
                   new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 this.maxFreeImmortal.setTupleMetaData(maxFreeImmortalMetaData);
                 TupleMetaData minpriorityMetaData = new TupleMetaData(TupleMetaData.TableType.ARITHMETIC, 
                   new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 this.minpriority.setTupleMetaData(minpriorityMetaData);
                 TupleMetaData maxpriorityMetaData = new TupleMetaData(TupleMetaData.TableType.ARITHMETIC, 
                   new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 this.maxpriority.setTupleMetaData(maxpriorityMetaData);
                 TupleMetaData objectsQueuedForFinalizationMetaData = new TupleMetaData(
                   TupleMetaData.TableType.ARITHMETIC, new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, 
                   TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX, TupleMetaData.TableField.TOTAL });
                 this.objectsQueuedForFinalization
                   .setTupleMetaData(objectsQueuedForFinalizationMetaData);
                 TupleMetaData softRefsClearedMetaData = new TupleMetaData(TupleMetaData.TableType.ARITHMETIC, 
                   new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX, TupleMetaData.TableField.TOTAL });
                 this.softRefsCleared.setTupleMetaData(softRefsClearedMetaData);
                 TupleMetaData weakRefsClearedMetaData = new TupleMetaData(TupleMetaData.TableType.ARITHMETIC, 
                   new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX, TupleMetaData.TableField.TOTAL });
                 this.weakRefsCleared.setTupleMetaData(weakRefsClearedMetaData);
                 TupleMetaData phantomRefsClearedMetaData = new TupleMetaData(TupleMetaData.TableType.ARITHMETIC, 
                   new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX, TupleMetaData.TableField.TOTAL });
                 this.phantomRefsCleared.setTupleMetaData(phantomRefsClearedMetaData);
                 TupleMetaData classesUnloadedMetaData = new TupleMetaData(TupleMetaData.TableType.ARITHMETIC, 
                   new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX, TupleMetaData.TableField.TOTAL });
                 this.classesUnloaded.setTupleMetaData(classesUnloadedMetaData);
                 TupleMetaData classloadersUnloadedMetaData = new TupleMetaData(TupleMetaData.TableType.ARITHMETIC, 
                   new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX, TupleMetaData.TableField.TOTAL });
                 this.classloadersUnloaded.setTupleMetaData(classloadersUnloadedMetaData);
                 TupleMetaData cycleIntervalsMetaData = new TupleMetaData(TupleMetaData.TableType.ARITHMETIC, 
                   new TupleMetaData.TableField[] { TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 this.cycleIntervals.setTupleMetaData(cycleIntervalsMetaData);
               }
               
               boolean hasInitialTime()
               {
                 return this.hasInitialTime;
               }
               
               void setInitialTime(long initialTimeMicros) {
                 this.initialTimeMicros = initialTimeMicros;
                 this.hasInitialTime = true;
               }
               
               long getInitialTimeMicros() {
                 return this.initialTimeMicros;
               }
               
               void completeGCEvent(String eventLabel, int eventConstant, long id, String currentComment) {
                 this.handler.handleGCActivity(eventLabel, eventConstant, id, currentComment);
                 this.handler.complete();
               }
               
               void addCurrentGCEvent(String eventLabel, int eventConstant, long id, String currentComment) {
                 this.handler.handleCurrentGCActivity(eventLabel, eventConstant, id, currentComment);
               }
               
               static long getClassesUnloaded(Attributes atts)
               {
                 String classes = atts.getValue("classes");
                 return convertPositiveInteger(classes);
               }
               
               static long getClassLoadersUnloaded(Attributes atts)
               {
                 String classes = atts.getValue("classloaders");
                 return convertPositiveInteger(classes);
               }
               
               void setXAxis(double timeMillis)
               {
                 this.xAxis.setX(timeMillis);
                 this.gcNumberConverter.addPoint(this.xAxis.getSequenceUID(), this.currentGCNumber);
               }
               
               void handleWarning(Attributes atts, long timeMillis, String comment)
               {
                 String details = atts.getValue("details");
                 if ((details != null) && (details.equals("overflow occured"))) {
                   handleEvent("overflow occured", 
                     10, timeMillis, comment);
                 }
               }
               
               void handleEvent(String eventLabel, int eventConstant, long timeMillis, String currentComment) {
                 this.handler.handleEvent(eventLabel, eventConstant, timeMillis, currentComment);
               }
               
               static long getRefsCleared(Attributes atts)
               {
                 long s = getSoftRefsCleared(atts);
                 long w = getWeakRefsCleared(atts);
                 long p = getPhantomRefsCleared(atts);
                 if (s < 0L) {
                   s = 0L;
                 }
                 if (w < 0L) {
                   w = 0L;
                 }
                 if (p < 0L) {
                   p = 0L;
                 }
                 return s + w + p;
               }
               
               static long getSoftRefsCleared(Attributes atts) {
                 return getRefsCleared(atts, "soft");
               }
               
               static long getWeakRefsCleared(Attributes atts) {
                 return getRefsCleared(atts, "weak");
               }
               
               static long getPhantomRefsCleared(Attributes atts) {
                 return getRefsCleared(atts, "phantom");
               }
               
               static long getRefsCleared(Attributes atts, String label) {
                 String str = atts.getValue(label);
                 return convertPositiveInteger(str);
               }
               
               static long getFinalizedCount(Attributes atts)
               {
                 String queuedString = atts.getValue("objectsqueued");
                 return convertPositiveInteger(queuedString);
               }
               
               static long convertPositiveInteger(String val) {
                 if ((val != null) && (val.length() > 0)) {
                   try {
                     return Long.parseLong(val);
                   } catch (NumberFormatException localNumberFormatException) {}
                 }
                 return -1L;
               }
               
               static double convertPositiveDouble(String val) {
                 if ((val != null) && (val.length() > 0)) {
                   try {
                     return Double.parseDouble(val);
                   } catch (NumberFormatException localNumberFormatException) {}
                 }
                 return -1.0D;
               }
             }
